package de.justphil.tcg.tcgserver.rest.db.mapstores;


import static de.justphil.tcg.tcgserver.commons.logging.TCGLogging.restLogger;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.TypedQuery;

import org.slf4j.Logger;

import com.hazelcast.core.MapStore;

import de.justphil.tcg.tcgserver.commons.domain.Deck;
import de.justphil.tcg.tcgserver.commons.management.Application;

public class DeckMapStore implements MapStore<Long, Long> {

	private static final Logger log = restLogger(DeckMapStore.class);
	
	private final EntityManagerFactory factory;

	public DeckMapStore() {
		log.debug("New object created!");
		factory = Application.getEntityManagerFactory();
	}
	
	@Override
	public Long load(Long deckId) {
		log.debug("load()");
		
		EntityManager em = factory.createEntityManager();
		
		Deck deck = em.find(Deck.class, deckId);
		//loadTransientFields(em, deck);
		
		em.close();
		
		if (deck != null) {
			return deck.getUserId();
		}
		else {
			return null;
		}
	}

	@Override
	public Map<Long, Long> loadAll(Collection<Long> deckIds) {
		log.debug("loadAll()");
		
		EntityManager em = factory.createEntityManager();
		Map<Long, Long> deckMap = new HashMap<Long, Long>();
		
		List<Deck> deckList = getDeckList(em);
		for(Deck deck : deckList) {
			
			//loadTransientFields(em, deck);
			deckMap.put(deck.getId(), deck.getUserId());
			
		}
		
		em.close();
		
		return deckMap;
	}

	@Override
	public Set<Long> loadAllKeys() {
		log.debug("loadAllKeys()");
		
		EntityManager em = factory.createEntityManager();
		
		Set<Long> deckIds = new HashSet<Long>();
		
		List<Deck> deckList = getDeckList(em);
		for (Deck deck : deckList) {
			deckIds.add(deck.getId());
		}
		
		em.close();
		
		return deckIds;
	}
	
	/*
	private void loadTransientFields(EntityManager em, Deck deck) {
		if (deck == null) {
			return;
		}
		
		for (CardInstance ci : deck.getCardInstances()) {
			LoadHelper.loadIncludingDecks(em, ci);
		}
	}
	*/
	
	private List<Deck> getDeckList(EntityManager em) {
		TypedQuery<Deck> q = em.createQuery("SELECT d FROM Deck d ORDER BY d.id", Deck.class);
		return q.getResultList();
	}

	@Override
	public void delete(Long deckId) {
		
		log.debug("delete()");
		
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Deck deck = em.find(Deck.class, deckId);
		if (deck != null) {
			em.remove(deck);
		}
		
		em.getTransaction().commit();
		em.close();
		
	}

	@Override
	public void deleteAll(Collection<Long> deckIds) {
		
		log.debug("deleteAll()");
		
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Deck deck = null;
		for (Long deckId : deckIds) {
			deck = em.find(Deck.class, deckId);
			if (deck != null) {
				em.remove(deck);
			}
		}
		
		em.getTransaction().commit();
		em.close();
		
	}

	@Override
	public void store(Long deckId, Long userId) {
		
		/*
		log.debug("store()");
		
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Deck pDeck = em.find(Deck.class, deckId);
		if (pDeck == null) {
			log.debug("em.persist()");
			em.persist(deck);
		}
		else {
			log.debug("em.merge()");
			em.merge(deck);
		}
		
		em.getTransaction().commit();
		em.close();
		*/
	}

	@Override
	public void storeAll(Map<Long, Long> deckMap) {
		/*
		log.debug("storeAll()");
		
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Deck pDeck	= null;
		Deck deck	= null;
		for (Long deckId : deckMap.keySet()) {
			deck = deckMap.get(deckId);
			
			pDeck = em.find(Deck.class, deckId);
			if (pDeck == null) {
				log.debug("em.persist()");
				em.persist(deck);
			}
			else {
				log.debug("em.merge()");
				em.merge(deck);
			}
		}
		
		em.getTransaction().commit();
		em.close();
		*/
	}

}
